package com.monster.starter.security.service.abs;

import com.monster.json.JsonUtils;
import com.monster.security.data.entity.RsaKey;
import com.monster.security.data.utils.RsaUtils;
import com.monster.starter.security.common.entity.SysRsaInfo;
import com.monster.starter.security.service.TransmissionCipherService;

import java.util.HashMap;
import java.util.LinkedList;

/**
 * 密钥管理接口的抽象实现
 * @author kuang
 */
public abstract class TransmissionCipherAbstractService implements TransmissionCipherService {
    /**
     * 密钥的承载个数
     */
    protected static final int SIZE = 30;
    /**
     * 可颁发给用户的密钥
     */
    protected CipherMap<String, SysRsaInfo> available = new CipherMap<>();

    /**
     * 创建一个默认的密钥信息
     * @param code 信息的编码
     * @return 密钥信息
     */
    protected SysRsaInfo createRsaInfo (String code) {
        // 添加一个新的密钥信息
        SysRsaInfo info = new SysRsaInfo();
        info.setCode(code);
        // 密钥信息(服务端)
        RsaKey servlet = RsaUtils.createRSAKey();
        // 密钥信息(客户端)
        RsaKey client = RsaUtils.createRSAKey();
        info.setCPrivateCipher(client.getPrivateKey());
        info.setCPublicCipher(client.getPublicKey());

        info.setSPrivateCipher(servlet.getPrivateKey());
        info.setSPublicCipher(servlet.getPublicKey());
        return info;
    }

    /**
     * 获取当前时间节点的密钥
     * @return 密钥信息
     */
    @Override
    public SysRsaInfo get() {
        return available.get();
    }
    /**
     * 通过编码获取一组密钥
     * @param key 密钥的编码
     * @return 密钥信息
     */
    @Override
    public SysRsaInfo get(String key) {
        return available.get(key);
    }


    /**
     * 内部维系map
     */
    public class CipherMap<String, SysRsaInfo> extends HashMap<String, SysRsaInfo> {
        /**
         * key的排序
         */
        LinkedList<String> keys = new LinkedList<>();

        @Override
        public SysRsaInfo get(Object key) {
            return super.get(key);
        }
        public SysRsaInfo get() {
            return super.get(keys.getLast());
        }
        @Override
        public SysRsaInfo put(String key, SysRsaInfo value) {
            if (keys.size() > SIZE) {
                super.remove(keys.getFirst());
                keys.removeFirst();
            }
            keys.addLast(key);
            return super.put(key, value);
        }

        @Override
        public SysRsaInfo remove(Object key) {
            keys.remove(key);
            return super.remove(key);
        }
    }
}
